/*
 * BlackLightning.PluginLib.Modules.PacketRegistrationMessage
 * Andy Tidball
 * 
 * Project: Black Lightning Plugin Library
 * Copyright: GNU General Public License
 */

using System;
using BlackLightning.PluginLib;
using BlackLightning.PluginLib.Modules.Packets;

namespace BlackLightning.PluginLib.Modules {
	/// <summary>
	/// A message dealing with registration of a packet filter.
	/// </summary>
	[Serializable]
	public class PacketRegistrationMessage : Message {
		// member data
		private BLPacketFilter _Filter; // the filter being registered/unregistered

		/// <summary>
		/// Creates a new RegistrationMessage.
		/// </summary>
		/// <param name="Filter">The filter that is the subject of the registration.</param>
		public PacketRegistrationMessage(BLPacketFilter Filter) {
			_Filter = Filter;
		}

		/// <summary>
		/// Gets the filter that is the subject of the registration.
		/// </summary>
		public BLPacketFilter Filter {
			get {
				return _Filter;
			}
		}
	}

	/// <summary>
	/// A message sent to Black Lightning to register a packet filter for the given object.
	/// </summary>
	[Serializable]
	public class RegisterPacketMessage : PacketRegistrationMessage {
		// member data
		private Priority _Priority;  // the priority level at which the object wishes to handle matching packets
		private bool _NewThread; // whether or not the object wishes to handle matching packets in a new thread

		/// <summary>
		/// Creates a new RegisterPacketMessage.
		/// </summary>
		/// <param name="Filter">The filter that will be registered.</param>
		public RegisterPacketMessage(BLPacketFilter Filter)
			: this(Filter, Priority.Normal, false) {
		}

		/// <summary>
		/// Creates a new RegisterPacketMessage.
		/// </summary>
		/// <param name="Filter">The filter that will be registered.</param>
		/// <param name="Priority">The priority level to handle matching packets at.</param>
		public RegisterPacketMessage(BLPacketFilter Filter, Priority Priority)
			: this(Filter, Priority, false) {
		}

		/// <summary>
		/// Creates a new RegisterPacketMessage.
		/// </summary>
		/// <param name="Filter">The filter that will be registered.</param>
		/// <param name="Priority">The priority level to handle matching packets at.</param>
		/// <param name="NewThread">Whether or not to handle matching packets in a new thread.</param>
		public RegisterPacketMessage(BLPacketFilter Filter, Priority Priority, bool NewThread)
			: base(Filter) {
			_Priority  = Priority;
			_NewThread = NewThread;
		}

		/// <summary>
		/// Gets the priority level at which the object wishes to handle matching packets.
		/// </summary>
		public Priority Priority {
			get {
				return _Priority;
			}
		}

		/// <summary>
		/// Gets whether or not the object wishes to handle matching packets in a new thread.
		/// </summary>
		public bool NewThread {
			get {
				return _NewThread;
			}
		}
	}

	/// <summary>
	/// The priority level at which a registered packet might be handled.
	/// </summary>
	public enum Priority {
		/// <summary>
		/// Items with this priority must be dealt with before any others.
		/// </summary>
		First,

		/// <summary>
		/// Items with this priority should be dealt with as early as possible.  This priority should only be used for objects which must view unaltered data from the source but not change it.
		/// </summary>
		Earlier,

		/// <summary>
		/// Items with this priority should be dealt with before standard items.  This priority should be used for objects which need to catch data before it's handled by standard objects.  It is recommended that objects don't modify data at this stage.
		/// </summary>
		Early,

		/// <summary>
		/// Items with this priority are dealt with the standard order.  This priority should be used by almost all objects, especially those where ordering isn't important.  It is most appropriate for objects which implement a custom command.
		/// </summary>
		Normal,

		/// <summary>
		/// Items with this priority should be dealt with after standard items.  This priority should be used for objects which "filter" data going from the source to the destination.  This is the best priority for objects to alter a packet's data.
		/// </summary>
		Late,

		/// <summary>
		/// Items with this priority should be dealt with as late as possible.  This priority should be used by objects which must view the final data being sent to the destination.
		/// </summary>
		Later,

		/// <summary>
		/// Items with this priority must be dealt with after any others.
		/// </summary>
		Last
	}

	/// <summary>
	/// A message sent to Black Lightning to unregister a packet filter for the given object.
	/// </summary>
	[Serializable]
	public class UnregisterPacketMessage : PacketRegistrationMessage {
		/// <summary>
		/// Creates a new UnregisterPacketMessage.
		/// </summary>
		/// <param name="Filter">The filter that will be unregistered.</param>
		public UnregisterPacketMessage(BLPacketFilter Filter)
			: base(Filter) {
		}
	}
}
